<template>
    <transition
        name="custom-classes-transition"
        enter-active-class="rambler__animated slideInRight"
        leave-active-class="rambler__animated slideOutRight"
        :duration="{enter:150, leave: 100}"
    >
        <div
            class="global-contentmenu-popup-container"
            v-if="visible"
            ref="menuRef"
            :style="{
                left: contextMenuPosition.left + 'px',
                top: contextMenuPosition.top + 'px',
                width: contextMenuWidth + 'px'
            }"
        >
            <template v-for="item in menus">
                <!-- 普通菜单 -->
                <div
                    class="contextmenu-item"
                    v-if="item.type === 'context-menu'"
                    is-single="true"
                    :key="item.id"
                >
                    <li @click.stop="item.click">
                        <basic-icon :name="item.icon" class="prefix-icon"></basic-icon>
                        <span>{{ item.label }}</span>
                    </li>
                </div>
                <!-- 快速链接 -->
                <div
                    class="contextmenu-item"
                    is-single="true"
                    v-else-if="
                        item.type === 'fast-links' && item.children && item.children.length > 0
                    "
                    @mouseenter="showSecondCtxMenu"
                    @mouseleave="hideSecondCtxMenu"
                >
                    <li @click.stop="() => {}">
                        <basic-icon name="fast" class="prefix-icon"></basic-icon>
                        <span>{{ item.label }}</span>
                        <basic-icon name="back" class="suffix-icon icon-flip"></basic-icon>
                    </li>
                    <transition
                        name="custom-classes-transition"
                        enter-active-class="rambler__animated fadeInRight"
                        leave-active-class="rambler__animated fadeOut"
                    >
                        <div
                            class="global-secondary-contextmenu-container"
                            v-show="showSecondMenu"
                            :style="secondMenuStyle"
                        >
                            <div class="secondary-contextmenu-inner">
                                <div
                                    class="contextmenu-item"
                                    is-single="true"
                                    v-for="fastlink of item.children"
                                    :key="fastlink.label"
                                >
                                    <li @click="visitFastLink(fastlink)">
                                        <!-- <basic-icon name="fast" class="prefix-icon"></basic-icon -->
                                        <span>{{ fastlink.label }}</span>
                                    </li>
                                </div>
                            </div>
                        </div>
                    </transition>
                </div>
                <div
                    v-else-if="item.type === 'context-menu-tags'"
                    class="contextmenu-item multi-contextmenu-item"
                >
                    <li>
                        <p>{{ item.label }}</p>
                    </li>
                    <div class="inner-box">
                        <span
                            v-for="layout of item.children"
                            @click.stop="updateType(layout.layout)"
                            :class="[type === layout.type ? 'choosen' : '']"
                        >{{ layout.type }}</span
                        >
                    </div>
                </div>
            </template>
        </div>
    </transition>
</template>

<script setup>
import {ref, defineProps, toRefs, onMounted, onBeforeUnmount, defineEmits} from 'vue'

const emit = defineEmits(['update:visible'])

const props = defineProps({
    contextMenuPosition: {
        type: Object,
        default: () => ({left: 0, top: 0})
    },
    contextMenuWidth: {
        type: Number,
        default: 200
    },
    menus: {
        type: Array,
        default: () => []
    },
    visible: {
        type: Boolean,
        default: false
    },
    // 类型(比如site样式, 某个组件主题等)
    type: {
        type: String,
        default: '1'
    }
})
// 初始定义secondMenuStyle是一个空对象, 所以需要 $set和 $delete来强制更新视图
const secondMenuStyle = ref({}) // 右键二级菜单位置
const menuRef = ref(null)
const showSecondMenu = ref(false)
const {contextMenuPosition, contextMenuWidth, menus, visible, type} = toRefs(props)

const closeMenu = () => {
    emit('update:visible', false)
    // visible.value = false
}

// 监听全局点击关闭菜单
const handleClickOutside = e => {
    if (!menuRef.value?.contains(e.target)) {
        closeMenu()
    }
}

const handleEsc = e => {
    if (e.key === 'Escape') {
        closeMenu()
    }
}

onMounted(() => {
    window.addEventListener('click', handleClickOutside)
    window.addEventListener('scroll', closeMenu, true)
    window.addEventListener('keydown', handleEsc)
})

onBeforeUnmount(() => {
    window.removeEventListener('click', handleClickOutside)
    window.removeEventListener('scroll', closeMenu, true)
    window.removeEventListener('keydown', handleEsc)
})

// 右键弹窗二级菜单显示
function showSecondCtxMenu() {
    // 初始定义secondMenuStyle是一个空对象, 所以需要 $set和 $delete来强制更新视图
    const viewPortWidth = document.documentElement.clientWidth
    // 一级弹窗和二级弹窗加起来都不超过可视窗口宽度, 可以在右侧展开二级菜单
    if (contextMenuPosition.value.left + contextMenuWidth.value * 2 >= viewPortWidth) {
        delete secondMenuStyle.value.left
        secondMenuStyle.value.right = '100%'
    } else {
        delete secondMenuStyle.value.right
        secondMenuStyle.value.left = '100%'
    }
    // 高度溢出先不考虑
    secondMenuStyle.value.top = '0'
    showSecondMenu.value = true
}

function hideSecondCtxMenu() {
    showSecondMenu.value = false
}

// 访问快速链接
function visitFastLink(fastlink) {
    window.open(fastlink.url, '_blank')
    closeMenu()
}
</script>
<style lang="less" scoped>
.global-contentmenu-popup-container {
    background-color: #2c2c2c;
    padding: 8px;
    position: fixed;
    border-radius: 8px;
    backdrop-filter: blur(3px);
    z-index: 999;

    .contextmenu-item {
        position: relative;
        width: 100%;

        li {
            border-radius: 3px;
            list-style: none;
            position: relative;
            display: block;
            width: 100%;
            height: 30px;
            color: #fff;
            font-size: 12px;
            line-height: 30px;
            box-sizing: border-box;
            padding-left: 5px;
            cursor: pointer;
            position: relative;

            .prefix-icon {
                fill: #fff;
                position: relative;
                top: -10px;
                margin-right: 6px;
            }

            .suffix-icon {
                position: absolute;
                right: 3px;
                top: 10px;
                fill: #fff;
            }

            span {
                display: inline-block;
                width: calc(100% - 24px);
                text-overflow: ellipsis;
                white-space: wrap;
                overflow: hidden;
                height: 30px;
            }

            .icon-flip {
                transform: rotate(180deg);
            }
        }
    }

    .contextmenu-item[is-single='true'] {
        li:hover {
            background: #575656;
            color: #fff;
        }
    }

    .global-secondary-contextmenu-container {
        padding-left: 9px;
        background: transparent;
        position: absolute;
        left: 100%;
        top: 0;

        .secondary-contextmenu-inner {
            background-color: #2c2c2c;
            width: 100px;
            border-radius: 8px;
            padding: 8px;
        }
    }

    .multi-contextmenu-item {
        p {
            margin: 0;
        }

        .inner-box {
            padding-left: 0px;

            span {
                display: inline-block;
                font-size: 10px;
                background-color: #737272;
                color: #fff;
                padding: 4px 6px;
                margin-right: 5px;
                border-radius: 3px;

                &:hover {
                    background-color: #624fe2;
                }
            }

            span.choosen {
                background-color: #624fe2;
            }
        }
    }
}

// 添加自定义动画类
.rambler__animated {
    animation-duration: 0.2s;
    animation-fill-mode: both;
}

.rambler__animated.slideInRight {
    animation-name: slideInRight;
}

.rambler__animated.slideOutRight {
    animation-name: slideOutRight;
}

@keyframes slideInRight {
    from {
        transform: translateX(20px);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes slideOutRight {
    from {
        transform: translateX(0);
        opacity: 1;
    }
    to {
        transform: translateX(20px);
        opacity: 0;
    }
}
</style>
